///////////////////////////////////////////////////////////////////////////////
//  Copyright 2010 Taesun Moon <tsunmoon@gmail.com>.
// 
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//  under the License.
///////////////////////////////////////////////////////////////////////////////
package opennlp.textgrounder.bayesian.rlda.io;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import opennlp.textgrounder.bayesian.apps.ExperimentParameters;

/**
 *
 * @author Taesun Moon <tsunmoon@gmail.com>
 */
public class RLDABinaryInputReader extends RLDAInputReader {

    protected DataInputStream tokenArrayInputStream;
    protected DataInputStream toponymRegionInputStream;

    public RLDABinaryInputReader(ExperimentParameters _experimentParameters) {
        super(_experimentParameters);
        openTokenArrayReader();
        openToponymRegionReader();
    }

    @Override
    public int[] nextTokenArrayRecord() throws EOFException, IOException {
        int[] record = new int[4];

        int wordid = tokenArrayInputStream.readInt();
        int docid = tokenArrayInputStream.readInt();
        int topstatus = (int) tokenArrayInputStream.readByte();
        int stopstatus = (int) tokenArrayInputStream.readByte();
        record[0] = wordid;
        record[1] = docid;
        record[2] = topstatus;
        record[3] = stopstatus;
        return record;
    }

    @Override
    public int[] nextToponymRegionFilter() throws EOFException, IOException {

        int topid = toponymRegionInputStream.readInt();
        int fieldsize = toponymRegionInputStream.readInt();
        int[] record = new int[fieldsize + 1];
        record[0] = topid;
        for (int i = 0; i < fieldsize; ++i) {
            record[i + 1] = toponymRegionInputStream.readInt();
        }

        return record;
    }

    @Override
    public int getMaxRegionID() {
        int maxreg = 0;
        try {
            while (true) {
                int topid = toponymRegionInputStream.readInt();
                int fieldsize = toponymRegionInputStream.readInt();
                int regid = 0;
                for (int i = 0; i < fieldsize; ++i) {
                    regid = toponymRegionInputStream.readInt();
                    if (regid > maxreg) {
                        maxreg = regid;
                    }
                }
            }
        } catch (EOFException e) {
            // do nothing and just continue
        } catch (IOException ex) {
            Logger.getLogger(RLDABinaryInputReader.class.getName()).log(Level.SEVERE, null, ex);
        }
        assert maxreg != 0;

        return maxreg;
    }

    @Override
    public final void openTokenArrayReader() {
        try {
            if (tokenArrayFile.getName().endsWith(".gz")) {
                tokenArrayInputStream = new DataInputStream(
                      new BufferedInputStream(new GZIPInputStream(new BufferedInputStream(new FileInputStream(tokenArrayFile)))));
            } else {
                tokenArrayInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(tokenArrayFile)));
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(RLDABinaryInputReader.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        } catch (IOException ex) {
            Logger.getLogger(RLDABinaryInputReader.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        }
    }

    @Override
    public final void openToponymRegionReader() {
        try {
            if (toponymRegionFile.getName().endsWith(".gz")) {
                toponymRegionInputStream = new DataInputStream(
                      new BufferedInputStream(new GZIPInputStream(new BufferedInputStream(new FileInputStream(toponymRegionFile)))));
            } else {
                toponymRegionInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(toponymRegionFile)));
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(RLDABinaryInputReader.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        } catch (IOException ex) {
            Logger.getLogger(RLDABinaryInputReader.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        }
    }

    @Override
    public void closeTokenArrayReader() {
        try {
            tokenArrayInputStream.close();
        } catch (IOException ex) {
        }
    }

    @Override
    public void closeToponymRegionReader() {
        try {
            toponymRegionInputStream.close();
        } catch (IOException ex) {
        }
    }

    @Override
    public void resetTokenArrayReader() {
        closeTokenArrayReader();
        openTokenArrayReader();
    }

    @Override
    public void resetToponymRegionReader() {
        closeToponymRegionReader();
        openToponymRegionReader();
    }
}
